﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web;

namespace PrinterMonitorSvc.Common
{
    /// <summary>
    /// 文件帮助类
    /// </summary>
    public static class FileHelper
    {
        #region 下载文件
        /// <summary>
        /// 普通下载文件
        /// </summary>
        /// <param name="content">文件内容</param>
        /// <param name="fileName">文件名</param>
        /// <param name="ext">文件后缀（eg:.xls）</param>
        public static void DownloadFile(byte[] content, string fileName, string ext)
        {
            try
            {
                var response = HttpContext.Current.Response;
                var request = HttpContext.Current.Request.UserAgent?.ToUpper();
                response.Clear();
                response.ClearHeaders();
                if (request != null && request.Contains("MSIE"))
                {
                    fileName = HttpUtility.UrlEncode(fileName);
                }
                response.Charset = "UTF-8";
                response.AddHeader("Content-Disposition", "attachment;filename=" + fileName + ext);
                response.AddHeader("Content-Length", content.Length.ToString());
                response.ContentType = "application/octet-stream";
                response.Buffer = false;
                response.BinaryWrite(content);
                response.Flush();
                response.End();
            }
            catch (Exception)
            {
                throw;
            }
        }


        /// <summary>
        /// 普通下载文件
        /// </summary>
        /// <param name="filePath">要下载的文件路径（默认为虚拟路径）</param>
        /// <param name="isVirtualDirectory">是否是虚拟目录</param>
        public static void DownloadFile(string filePath, bool isVirtualDirectory)
        {
            try
            {
                var fileUrl = isVirtualDirectory ? MapVirtualPath(filePath) : filePath;
                var file = new FileInfo(fileUrl);
                var response = HttpContext.Current.Response;
                var request = HttpContext.Current.Request.UserAgent?.ToUpper();
                var fileName = Path.GetFileName(fileUrl);
                response.Clear();
                response.ClearHeaders();
                if (request != null && request.Contains("MSIE"))
                {
                    fileName = HttpUtility.UrlEncode(fileName);
                }
                response.Charset = "UTF-8";
                response.AddHeader("Content-Disposition", "attachment;filename=" + fileName);
                response.AddHeader("Content-Length", file.Length.ToString());
                response.ContentType = "application/octet-stream";
                response.Buffer = false;
                response.WriteFile(fileUrl);
                response.Flush();
                response.End();
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 大文件分块下载
        /// </summary>
        /// <param name="fileName">文件虚拟路径</param>
        /// <param name="blockSize">指定块大小(默认200K)</param>
        /// <param name="isVirtualDirectory">是否是虚拟目录</param>
        public static void DownLoadFileByBlock(string fileName, long blockSize = 204800, bool isVirtualDirectory = true)
        {
            var response = HttpContext.Current.Response;
            var request = HttpContext.Current.Request.UserAgent;
            string filePath = isVirtualDirectory ? MapVirtualPath(fileName) : fileName;
            var name = Path.GetFileName(filePath);//文件名称
            long chunkSize = blockSize;             //指定块大小 
            byte[] buffer = new byte[chunkSize]; //建立一个200K的缓冲区 
            long dataToRead = 0;                 //已读的字节数   
            FileStream stream = null;
            try
            {
                if (request != null && request.Contains("MSIE"))
                {
                    name = HttpUtility.UrlEncode(fileName);
                }

                //打开文件   
                stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
                dataToRead = stream.Length;

                //添加Http头   
                response.ContentType = "application/octet-stream";
                response.AddHeader("Content-Disposition", "attachement;filename=" + name);
                response.AddHeader("Content-Length", dataToRead.ToString());

                while (dataToRead > 0)
                {
                    if (response.IsClientConnected)
                    {
                        int length = stream.Read(buffer, 0, Convert.ToInt32(chunkSize));
                        response.OutputStream.Write(buffer, 0, length);
                        response.Flush();
                        response.Clear();
                        dataToRead -= length;
                    }
                    else
                    {
                        dataToRead = -1; //防止client失去连接 
                    }
                }
            }
            catch (Exception ex)
            {
                response.Write("下载失败,原因为:" + ex.Message);
            }
            finally
            {
                stream?.Close();
                response.Close();
            }
        }

        /// <summary>
        ///  输出硬盘文件，提供下载 支持大文件、续传、速度限制、资源占用小
        /// </summary>
        /// <param name="fullPath">带文件名下载路径</param>
        /// <param name="speed"> 下载速度（kb/s）</param>
        /// <param name="isVirtualDirectory">是否是虚拟目录</param>
        /// <returns>返回是否成功</returns>
        //---------------------------------------------------------------------
        //调用：
        // DownLoadFile("/File/count.txt",100);
        //---------------------------------------------------------------------
        public static bool DownLoadFile(string fullPath, long speed, bool isVirtualDirectory = true)
        {
            try
            {
                speed = speed * 1024;
                var _Request = HttpContext.Current.Request;
                var _Response = HttpContext.Current.Response;
                var _fileUrl = isVirtualDirectory ? MapVirtualPath(fullPath) : fullPath;
                var _fileName = Path.GetFileName(_fileUrl);
                FileStream myFile = new FileStream(_fileUrl, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                BinaryReader br = new BinaryReader(myFile);
                try
                {
                    _Response.AddHeader("Accept-Ranges", "bytes");
                    _Response.Buffer = false;

                    long fileLength = myFile.Length;
                    long startBytes = 0;
                    int pack = 10240;  //10K bytes
                    int sleep = (int)Math.Floor((double)(1000 * pack / speed)) + 1;

                    if (_Request.Headers["Range"] != null)
                    {
                        _Response.StatusCode = 206;
                        string[] range = _Request.Headers["Range"].Split('=', '-');
                        startBytes = Convert.ToInt64(range[1]);
                    }
                    _Response.AddHeader("Content-Length", (fileLength - startBytes).ToString());
                    if (startBytes != 0)
                    {
                        _Response.AddHeader("Content-Range", $" bytes {startBytes}-{fileLength - 1}/{fileLength}");
                    }
                    if (_Request.UserAgent != null && _Request.UserAgent.Contains("MSIE"))
                    {
                        _fileName = HttpUtility.UrlEncode(_fileName);
                    }
                    _Response.AddHeader("Connection", "Keep-Alive");
                    _Response.ContentType = "application/octet-stream";
                    _Response.AddHeader("Content-Disposition", "attachment;filename=" + _fileName);

                    br.BaseStream.Seek(startBytes, SeekOrigin.Begin);
                    int maxCount = (int)Math.Floor((double)((fileLength - startBytes) / pack)) + 1;

                    for (int i = 0; i < maxCount; i++)
                    {
                        if (_Response.IsClientConnected)
                        {
                            _Response.BinaryWrite(br.ReadBytes(pack));
                            Thread.Sleep(sleep);
                        }
                        else
                        {
                            i = maxCount;
                        }
                    }
                }
                catch
                {
                    return false;
                }
                finally
                {
                    br.Close();
                    myFile.Close();
                }
            }
            catch
            {
                return false;
            }
            return true;

        }
        #endregion

        #region 读取文件内容
        /// <summary>
        /// 读取文件内容
        /// </summary>
        /// <param name="path">文件路径</param>
        /// <param name="isVirtualDirectory">是否是虚拟目录</param>
        /// <returns>字符串</returns>
        public static string ReadFile(string path, bool isVirtualDirectory)
        {
            path = isVirtualDirectory ? MapVirtualPath(path) : path;
            if (File.Exists(path))
            {
                try
                {
                    using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
                    {
                        using (StreamReader reader = new StreamReader(fs, Encoding.UTF8))
                        {
                            return reader.ReadToEnd();
                        }
                    }

                }
                catch (Exception)
                {
                    return string.Empty;
                }

            }
            return string.Empty;
        }
        #endregion

        #region 将虚拟路径映射到实际路径
        /// <summary>
        /// 将虚拟路径映射到实际路径
        /// </summary>
        /// <param name="virtualPath">虚拟路径</param>
        /// <returns></returns>
        public static string MapVirtualPath(string virtualPath)
        {
            string path;
            if (virtualPath.StartsWith("~/"))
            {
                path = virtualPath.Remove(0, 2);
            }
            else if (virtualPath.StartsWith("/"))
            {
                path = virtualPath.Remove(0, 1);
            }
            else
            {
                path = virtualPath;
            }
            path = path.Replace("/", "\\");
            return (HttpContext.Current != null ? (HttpRuntime.AppDomainAppPath) : (Environment.CurrentDirectory + "\\")) + path;
        }
        #endregion

        #region GetFileControls(获取客户端文件控件集合)

        /// <summary>
        /// 获取有效客户端文件控件集合,文件控件必须上传了内容，为空将被忽略,
        /// 注意:Form标记必须加入属性 enctype="multipart/form-data",服务器端才能获取客户端file控件.
        /// </summary>
        public static List<HttpPostedFile> GetFileControls()
        {
            var result = new List<HttpPostedFile>();
            var files = HttpContext.Current.Request.Files;
            if (files.Count == 0)
                return result;
            for (int i = 0; i < files.Count; i++)
            {
                var file = files[i];
                if (file.ContentLength == 0)
                    continue;
                result.Add(files[i]);
            }
            return result;
        }

        #endregion

        #region GetFileControl(获取第一个有效客户端文件控件)

        /// <summary>
        /// 获取第一个有效客户端文件控件,文件控件必须上传了内容，为空将被忽略,
        /// 注意:Form标记必须加入属性 enctype="multipart/form-data",服务器端才能获取客户端file控件.
        /// </summary>
        public static HttpPostedFile GetFileControl()
        {
            var files = GetFileControls();
            if (files == null || files.Count == 0)
                return null;
            return files[0];
        }

        #endregion

        #region 保存文件
        /// <summary>
        /// 保存文件
        /// </summary>
        /// <param name="content">内容</param>
        /// <param name="filePath">文件物理路径</param>
        /// <returns></returns>
        public static bool SaveFile(string content, string filePath)
        {
            try
            {
                string directory = filePath.Substring(0, filePath.LastIndexOf('\\'));
                if (!Directory.Exists(directory))
                {
                    Directory.CreateDirectory(directory);
                }
                File.WriteAllText(filePath, content, Encoding.UTF8);
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        /// <summary>
        /// 通过追加的方式保存文件
        /// </summary>
        /// <param name="content">内容</param>
        /// <param name="filePath">文件物理路径</param>
        /// <returns></returns>
        public static bool SaveFileByAppend(string content, string filePath)
        {
            try
            {
                string directory = filePath.Substring(0, filePath.LastIndexOf('\\'));
                if (!Directory.Exists(directory))
                {
                    Directory.CreateDirectory(directory);
                }
                using (StreamWriter writer = new StreamWriter(filePath, append: true, Encoding.UTF8))
                {
                    writer.WriteLine(content);
                    writer.Flush();
                }
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }
        #endregion

        #region 复制文件
        /// <summary>
        /// 复制目录下所有文件到目标目录
        /// </summary>
        /// <param name="srcPath">源目录</param>
        /// <param name="destPath">目标目录</param>
        public static void CopyDirectory(string srcPath, string destPath)
        {
            try
            {
                if (!Directory.Exists(destPath))
                {
                    Directory.CreateDirectory(destPath);
                }
                DirectoryInfo dir = new DirectoryInfo(srcPath);
                FileSystemInfo[] fileinfo = dir.GetFileSystemInfos();
                foreach (FileSystemInfo i in fileinfo)
                {
                    if (i is DirectoryInfo)
                    {
                        CopyDirectory(i.FullName, destPath + "\\" + i.Name);
                    }
                    else
                    {
                        File.Copy(i.FullName, destPath + "\\" + i.Name, true);
                    }
                }
            }
            catch (Exception)
            {
                throw;
            }
        }
        #endregion

        #region 获取目录下所有文件
        /// <summary>
        /// 获取目录下所有文件
        /// </summary>
        /// <param name="srcPath">源目录</param>
        /// <param name="searchSubDirectory">是否搜索子目录</param>
        public static List<FileSystemInfo> GetAllFiles(string srcPath, bool searchSubDirectory)
        {
            List<FileSystemInfo> fileList = new List<FileSystemInfo>();
            try
            {
                if (Directory.Exists(srcPath))
                {
                    DirectoryInfo dir = new DirectoryInfo(srcPath);
                    FileSystemInfo[] fileinfo = dir.GetFileSystemInfos();
                    foreach (FileSystemInfo i in fileinfo)
                    {
                        if (i is DirectoryInfo)
                        {
                            if (searchSubDirectory)
                            {
                                fileList.AddRange(GetAllFiles(i.FullName, searchSubDirectory));
                            }
                        }
                        else
                        {
                            fileList.Add(i);
                        }
                    }
                }

                return fileList;
            }
            catch (Exception)
            {
                throw;
            }
        }
        #endregion

        #region 生成临时文件
        /// <summary>
        /// 根据URL生成临时文件并返回本地完整文件路径
        /// </summary>
        /// <param name="url">完整URL地址</param>
        /// <param name="ext">生成的文件扩展名(如.pdf)</param>
        /// <param name="timeout">超时时间(以毫秒为单位,默认30秒)</param>
        /// <returns>本地完整文件路径</returns>
        public static string GenTempFile(string url, string ext, int timeout = 30000)
        {
            var path = Path.GetTempFileName();
            var newPath = Path.ChangeExtension(path, ext);
            File.Move(path, newPath);
            var content = DownloadData(url, timeout: timeout);
            using (FileStream fileStream = new FileStream(newPath, FileMode.Open))
            {
                fileStream.Write(content, 0, content.Length);
                fileStream.Flush();
                fileStream.Close();
            }
            return newPath;
        }

        /// <summary>
        /// 生成本地临时文件
        /// </summary>
        /// <param name="ext">生成的文件扩展名(如.pdf)</param>
        /// <returns>本地完整文件路径</returns>
        public static string GenTempFile(string ext)
        {
            var path = Path.GetTempFileName();
            var newPath = Path.ChangeExtension(path, ext);
            File.Move(path, newPath);
            return newPath;
        }
        #endregion

        #region WebClient方式

        #region 下载文件或数据

        #region 异步
        /// <summary>
        /// 从远端异步下载文件到本地(不阻塞调用线程)
        /// </summary>
        /// <param name="remoteUrl">远端文件地址</param>
        /// <param name="localDir">本地文件目录</param>
        /// <param name="fileName">本地文件名称</param>
        /// <param name="progressAction">下载进度改变事件</param>
        /// <param name="completedAction">文件下载完成事件</param>
        /// <param name="userToken">用户参数，在Completed事件中通过UserState取出</param>
        /// <param name="headers">请求头信息</param>
        public static async Task DownloadFileAsync(string remoteUrl, string localDir, string fileName, DownloadProgressChangedEventHandler progressAction = null, AsyncCompletedEventHandler completedAction = null, object userToken = null, IDictionary<string, string> headers = null)
        {
            if (!Directory.Exists(localDir))
            {
                Directory.CreateDirectory(localDir);
            }
            await Task.Run(() =>
            {
                try
                {
                    using (WebClient client = new WebClient())
                    {
                        AddHeaders(client, headers);
                        client.DownloadProgressChanged += progressAction;
                        client.DownloadFileCompleted += completedAction;
                        client.DownloadFileAsync(new Uri(remoteUrl), Path.Combine(localDir, fileName), userToken);
                    }
                }
                catch (Exception)
                {
                    throw;
                }
            });
        }

        /// <summary>
        /// 从远端异步下载数据并返回(不阻塞调用线程)
        /// </summary>
        /// <param name="remoteUrl">远端文件地址</param>
        /// <param name="progressAction">下载进度改变事件</param>
        /// <param name="completedAction">数据下载完成事件</param>
        /// <param name="userToken">用户参数，在Completed事件中通过UserState取出</param>
        /// <param name="headers">请求头信息</param>
        public static async Task DownloadDataAsync(string remoteUrl, DownloadProgressChangedEventHandler progressAction = null, DownloadDataCompletedEventHandler completedAction = null, object userToken = null, IDictionary<string, string> headers = null)
        {
            await Task.Run(() =>
            {
                try
                {
                    using (WebClient client = new WebClient())
                    {
                        AddHeaders(client, headers);
                        client.DownloadProgressChanged += progressAction;
                        client.DownloadDataCompleted += completedAction;
                        client.DownloadDataAsync(new Uri(remoteUrl), userToken);
                    }
                }
                catch (Exception)
                {
                    throw;
                }
            });
        }

        /// <summary>
        /// 从远端异步下载字符串并返回(不阻塞调用线程)
        /// </summary>
        /// <param name="remoteUrl">远端文件地址</param>
        /// <param name="progressAction">下载进度改变事件</param>
        /// <param name="completedAction">数据下载完成事件</param>
        /// <param name="userToken">用户参数，在Completed事件中通过UserState取出</param>
        /// <param name="headers">请求头信息</param>
        public static async Task DownloadStrAsync(string remoteUrl, DownloadProgressChangedEventHandler progressAction = null, DownloadStringCompletedEventHandler completedAction = null, object userToken = null, IDictionary<string, string> headers = null)
        {
            await Task.Run(() =>
            {
                try
                {
                    using (WebClient client = new WebClient())
                    {
                        AddHeaders(client, headers);
                        client.DownloadProgressChanged += progressAction;
                        client.DownloadStringCompleted += completedAction;
                        client.DownloadStringAsync(new Uri(remoteUrl), userToken);
                    }
                }
                catch (Exception)
                {
                    throw;
                }
            });
        }
        #endregion

        #region 同步
        /// <summary>
        /// 从远端同步下载文件到本地(阻塞调用线程)
        /// </summary>
        /// <param name="remoteUrl">远端文件地址</param>
        /// <param name="localDir">本地文件目录</param>
        /// <param name="fileName">本地文件名称</param>
        /// <param name="headers">请求头信息</param>
        public static void DownloadFile(string remoteUrl, string localDir, string fileName, IDictionary<string, string> headers = null)
        {
            try
            {
                if (!Directory.Exists(localDir))
                {
                    Directory.CreateDirectory(localDir);
                }
                using (WebClient client = new WebClient())
                {
                    AddHeaders(client, headers);
                    client.DownloadFile(new Uri(remoteUrl), Path.Combine(localDir, fileName));
                }
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 从远端同步下载数据并返回(阻塞调用线程)
        /// </summary>
        /// <param name="remoteUrl">远端文件地址</param>
        /// <param name="headers">请求头信息</param>
        /// <param name="timeout">超时时间(以毫秒为单位,默认30秒)</param>
        public static byte[] DownloadData(string remoteUrl, IDictionary<string, string> headers = null, int timeout = 30000)
        {
            try
            {
                using (WebClientHelper client = new WebClientHelper(timeout))
                {
                    AddHeaders(client, headers);
                    return client.DownloadData(new Uri(remoteUrl));
                }
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 从远端同步下载字符串并返回(阻塞调用线程)
        /// </summary>
        /// <param name="remoteUrl">远端文件地址</param>
        /// <param name="headers">请求头信息</param>
        public static string DownloadStr(string remoteUrl, IDictionary<string, string> headers = null)
        {
            try
            {
                using (WebClient client = new WebClient())
                {
                    AddHeaders(client, headers);
                    return client.DownloadString(new Uri(remoteUrl));
                }
            }
            catch (Exception)
            {
                throw;
            }
        }
        #endregion

        #endregion

        #region 上传文件或数据

        #region 异步
        /// <summary>
        /// 从本地异步保存文件到远端(不阻塞调用线程)
        /// </summary>
        /// <param name="remoteUrl">远端文件地址</param>
        /// <param name="fileName">本地文件名称</param>
        /// <param name="method">上传方式(默认POST)</param>
        /// <param name="progressAction">上传进度改变事件</param>
        /// <param name="completedAction">文件上传完成事件</param>
        /// <param name="userToken">用户参数，在Completed事件中通过UserState取出</param>
        /// <param name="headers">请求头信息</param>
        public static async Task UploadFileAsync(string remoteUrl, string fileName, string method = "POST", UploadProgressChangedEventHandler progressAction = null, UploadFileCompletedEventHandler completedAction = null, object userToken = null, IDictionary<string, string> headers = null)
        {
            await Task.Run(() =>
            {
                try
                {
                    if (!File.Exists(fileName))
                    {
                        throw new FileNotFoundException("文件不存在", fileName);
                    }
                    using (WebClient client = new WebClient())
                    {
                        AddHeaders(client, headers);
                        client.UploadProgressChanged += progressAction;
                        client.UploadFileCompleted += completedAction;
                        client.UploadFileAsync(new Uri(remoteUrl), method, fileName, userToken);
                    }
                }
                catch (Exception)
                {
                    throw;
                }
            });
        }

        /// <summary>
        /// 从本地异步上传数据并返回结果(不阻塞调用线程)
        /// </summary>
        /// <param name="remoteUrl">远端文件地址</param>
        /// <param name="data">上传的数据</param>
        /// <param name="method">上传方式(默认POST)</param>
        /// <param name="progressAction">上传进度改变事件</param>
        /// <param name="completedAction">数据上传完成事件</param>
        /// <param name="userToken">用户参数，在Completed事件中通过UserState取出</param>
        /// <param name="headers">请求头信息</param>
        public static async Task UploadDataAsync(string remoteUrl, byte[] data, string method = "POST", UploadProgressChangedEventHandler progressAction = null, UploadDataCompletedEventHandler completedAction = null, object userToken = null, IDictionary<string, string> headers = null)
        {
            await Task.Run(() =>
            {
                try
                {
                    using (WebClient client = new WebClient())
                    {
                        AddHeaders(client, headers);
                        client.UploadProgressChanged += progressAction;
                        client.UploadDataCompleted += completedAction;
                        client.UploadDataAsync(new Uri(remoteUrl), method, data, userToken);
                    }
                }
                catch (Exception)
                {
                    throw;
                }
            });
        }

        /// <summary>
        /// 从本地异步上传字符串并返回结果(不阻塞调用线程)
        /// </summary>
        /// <param name="remoteUrl">远端文件地址</param>
        /// <param name="data">上传的数据</param>
        /// <param name="method">上传方式(默认POST)</param>
        /// <param name="progressAction">上传进度改变事件</param>
        /// <param name="completedAction">数据上传完成事件</param>
        /// <param name="userToken">用户参数，在Completed事件中通过UserState取出</param>
        /// <param name="headers">请求头信息</param>
        public static async Task UploadStrAsync(string remoteUrl, string data, string method = "POST", UploadProgressChangedEventHandler progressAction = null, UploadStringCompletedEventHandler completedAction = null, object userToken = null, IDictionary<string, string> headers = null)
        {
            await Task.Run(() =>
            {
                try
                {
                    using (WebClient client = new WebClient())
                    {
                        AddHeaders(client, headers);
                        client.UploadProgressChanged += progressAction;
                        client.UploadStringCompleted += completedAction;
                        client.UploadStringAsync(new Uri(remoteUrl), method, data, userToken);
                    }
                }
                catch (Exception)
                {
                    throw;
                }
            });
        }
        #endregion

        #region 同步
        /// <summary>
        /// 从本地同步保存文件到远端(阻塞调用线程)
        /// </summary>
        /// <param name="remoteUrl">远端文件地址</param>
        /// <param name="fileName">本地文件名称</param>
        /// <param name="method">上传方式(默认POST)</param>
        /// <param name="headers">请求头信息</param>
        public static byte[] UploadFile(string remoteUrl, string fileName, string method = "POST", IDictionary<string, string> headers = null)
        {
            try
            {
                if (!File.Exists(fileName))
                {
                    throw new FileNotFoundException("文件不存在", fileName);
                }
                using (WebClient client = new WebClient())
                {
                    AddHeaders(client, headers);
                    return client.UploadFile(new Uri(remoteUrl), method, fileName);
                }
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 从本地同步上传数据并返回结果(阻塞调用线程)
        /// </summary>
        /// <param name="remoteUrl">远端文件地址</param>
        /// <param name="data">上传的数据</param>
        /// <param name="method">上传方式(默认POST)</param>
        /// <param name="headers">请求头信息</param>
        public static byte[] UploadData(string remoteUrl, byte[] data, string method = "POST", IDictionary<string, string> headers = null)
        {
            try
            {
                using (WebClient client = new WebClient())
                {
                    AddHeaders(client, headers);
                    return client.UploadData(new Uri(remoteUrl), method, data);
                }
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 从本地同步上传字符串并返回结果(阻塞调用线程)
        /// </summary>
        /// <param name="remoteUrl">远端文件地址</param>
        /// <param name="data">上传的数据</param>
        /// <param name="method">上传方式(默认POST)</param>
        /// <param name="headers">请求头信息</param>

        public static string UploadStr(string remoteUrl, string data, string method = "POST", IDictionary<string, string> headers = null)
        {
            try
            {
                using (WebClient client = new WebClient())
                {
                    AddHeaders(client, headers);
                    return client.UploadString(new Uri(remoteUrl), method, data);
                }
            }
            catch (Exception)
            {
                throw;
            }
        }
        #endregion

        #endregion

        #region 私有方法

        /// <summary>
        /// 添加请求头
        /// </summary>
        /// <param name="client"></param>
        /// <param name="headers"></param>
        private static void AddHeaders(WebClient client, IDictionary<string, string> headers)
        {
            if (headers == null || headers.Count <= 0)
            {
                client.Headers.Add("Content-Type", "application/json");
            }
            else
            {
                foreach (var item in headers)
                {
                    client.Headers.Add(item.Key, item.Value);
                }
            }
        }

        #endregion

        #endregion

    }
}
